/**
 * 
 */
package info.niwota.profile.client;

import info.niwota.commons.web.JsonObject;
import info.niwota.profile.Debug;
import info.niwota.profile.Preferences;
import info.niwota.profile.http.AsyncHttpClient;
import info.niwota.profile.http.JsonHttpResponseHandler;
import info.niwota.profile.http.RequestParams;
import info.niwota.profile.shared.CryptUtils;

import java.security.KeyPair;

import org.json.JSONObject;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

/**
 * @author qiangli
 * 
 */
public class HttpClient {
	public static final String BASE_URL = "http://10.0.0.95:8888/";

	private static final String CREATE_PROFILE_URL = BASE_URL
			+ "jsonp/profile/createProfile";

	private static final String UPDATE_PROFILE_URL = BASE_URL
			+ "jsonp/profile/updateProfile";

	private static final String TAG = "HttpClient";

	private AsyncHttpClient http = null;

	public HttpClient() {
		this.http = new AsyncHttpClient();
	}

	public void updateProfile(final Context ctx, String id, final JSONObject obj)
			throws Exception {
		
		if (Debug.DEBUG){
			Log.d(TAG, obj.toString());
		}
		
		final String prikey = Preferences.getHttpPrivateKey(ctx);
		final String data = obj.toString();
		final String digest = CryptUtils.digest(data);
		final String encmd = CryptUtils.encrypt(CryptUtils.toPrivateKey(prikey), digest);
		
		final RequestParams params = new RequestParams();
		
		params.put("id", id);
		params.put("md", encmd);
		params.put("data", data);
		
		http.post(UPDATE_PROFILE_URL, params, new JsonHttpResponseHandler() {

			@Override
			public void onSuccess(JSONObject response) {
				try {
					if (Debug.DEBUG){
						Log.d(TAG, response.toString());
					}
					boolean rc = response.getBoolean("rc");
					if (rc) {
						String updated = response.getString("updated");
						Preferences.putProfileUpdated(ctx, updated);
					} else {
						String error = response.getString("error");
						if ("404".startsWith(error)) {
							//not found
							Preferences.removeProfileId(ctx);
							//
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			@Override
			public void onFailure(Throwable error, String content) {
				if (Debug.DEBUG){
					Log.d(TAG, "" + content);
				}
				
				error.printStackTrace();
			}
			
		});
	}

	public void createProfile(final Context ctx, JSONObject obj) throws Exception {
		if (Debug.DEBUG){
			Log.d(TAG, obj.toString());
		}
		
		KeyPair kp = CryptUtils.generateKeyPair();

		String prikey = CryptUtils.getPrivateKey(kp);
		String pubkey = CryptUtils.getPublicKey(kp);

		// save private key
		Preferences.putHttpPrivateKey(ctx, prikey);
		
		final String data = obj.toString();
		final String digest = CryptUtils.digest(data);
		final String encmd = CryptUtils.encrypt(CryptUtils.toPrivateKey(prikey), digest);
	
		final RequestParams params = new RequestParams();
		params.put("key", pubkey);
		params.put("md", encmd);
		params.put("data", data);
		
		http.post(CREATE_PROFILE_URL, params, new JsonHttpResponseHandler() {
			@Override
			public void onSuccess(JSONObject response) {
				try {
					if (Debug.DEBUG){
						Log.d(TAG, response.toString());
					}
					
					boolean rc = response.getBoolean("rc");
					if (rc) {
						String id = response.getString("id");
						String updated = response.getString("updated");
						
						//expecting id
						if (!TextUtils.isEmpty(id)) {
							Preferences.putProfileId(ctx, id, updated);
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			
			@Override
			public void onFailure(Throwable error, String content) {
				if (Debug.DEBUG){
					Log.d(TAG, "" + content);
				}
				
				error.printStackTrace();
			}
		});
	}
	
	private static HttpClient mHttpClient = new HttpClient();
	
	public static void updateProfile(final Context ctx) {
	
		try {
			String id = Preferences.getProfileId(ctx);

			JSONObject data = new JSONObject();
			JsonObject p = Preferences.getProfileJSONObject(ctx, false);

			data.put("name", p.get(Preferences.PROFILE_NAME));
			data.put("email", p.get(Preferences.PROFILE_EMAIL));
			data.put("profile", p.toString());

			if (TextUtils.isEmpty(id)) {
				mHttpClient.createProfile(ctx, data);

			} else {
				data.put("id", id);

				mHttpClient.updateProfile(ctx, id, data);
			}

		} catch (Exception e) {
			Toast.makeText(ctx, e.getMessage() + "", Toast.LENGTH_SHORT).show();
			
			e.printStackTrace();
		}
	}
}

//String url = profileUri.buildUpon().appendPath("createProfile")
//.toString();
//
//HttpPost httpPost = new HttpPost(url);
//
//List<NameValuePair> nvp = new ArrayList<NameValuePair>(2);
//
//nvp.add(new BasicNameValuePair("key", pubkey));
//nvp.add(new BasicNameValuePair("data", CryptUtils.encrypt(
//CryptUtils.toPrivateKey(prikey), data.toString())));
//
//httpPost.setEntity(new UrlEncodedFormEntity(nvp, "UTF-8"));
//
//// httpPost.setEntity(new StringEntity(profile.toString(),
//// "UTF-8"));
//
//if (Log.isLoggable(TAG, Log.VERBOSE)) {
//Log.v(TAG, "POST request: " + data.toString());
//}
//
//HttpResponse httpResponse = http.execute(httpPost);
//final int responseStatusCode = httpResponse.getStatusLine()
//.getStatusCode();
//if (200 <= responseStatusCode && responseStatusCode < 300) {
//BufferedReader reader = new BufferedReader(new InputStreamReader(
//	httpResponse.getEntity().getContent(), "UTF-8"), 8 * 1024);
//
//StringBuilder sb = new StringBuilder();
//String line;
//while ((line = reader.readLine()) != null) {
//sb.append(line).append("\n");
//}
//
//if (Log.isLoggable(TAG, Log.VERBOSE)) {
//Log.v(TAG, "POST response: " + sb.toString());
//}
//
//JSONTokener tokener = new JSONTokener(sb.toString());
//
//return new JSONObject(tokener);
//}
//
//return null;